home *** CD-ROM | disk | FTP | other *** search
Text File | 1989-06-18 | 6.2 KB | 262 lines | [TEXT/MPS ] |
- (****************************************************)
- (* *)
- (* file: CarWash.m *)
- (* *)
- (* Car Wash simulation using SimulationToolbox. *)
- (* *)
- (* REFERENCE: Goldberg and Robson, SMALLTALK-80: *)
- (* THE LANGUAGE AND ITS IMPLEMENTATION, *)
- (* pp. 518-521. *)
- (* *)
- (* Written in SemperSoft Modula-2 v.1.1.2 *)
- (* *)
- (* Allen Stenger May 1989 *)
- (* *)
- (****************************************************)
-
- MODULE CarWash;
-
- FROM SYSTEM IMPORT ADDRESS,ADR;
- FROM InOut IMPORT ReadCard,Write,
- WriteCard,WriteLn,
- WriteString;
- FROM Terminal IMPORT WritePString;
- FROM SimulationToolbox IMPORT Duration,Requester,
- SimulationQueue;
- FROM SimulationToolbox IMPORT CreateNewThread,
- CurrentTime,HaltThread,
- HaltSimulation,Hold,
- InitializeQueue,
- PlaceOrder,Reactivate,
- Serve;
- FROM Distributions IMPORT ExponentialDistribution,
- UniformDistribution;
-
- CONST
- WS = 8192; (* default work size *)
-
- (* Note:
- Times (Duration type) are in 0.01-minute units. *)
-
- WashArrivalMean
- = 2000; (* mean arrival time for
- wash only *)
- WashAndWaxArrivalMean
- = 3000; (* mean arrival time for
- wash and wax *)
- MinWashTime = 1200; (* min and max wash times *)
- MaxWashTime = 2600;
- MinWaxTime = 800; (* min and max wax times *)
- MaxWaxTime = 1200;
-
- TYPE
- DesiredService = ( Wash, WashAndWax );
- WasherParams = RECORD
- (* for starting washer thread *)
- WhoAmI : CARDINAL;
- END; (* RECORD *)
- CarParams = RECORD
- (* for starting car thread *)
- WhoAmI : CARDINAL;
- type : DesiredService;
- END; (* RECORD *)
- ServiceParams = RECORD
- (* describes car wanting service *)
- Car : CARDINAL;
- Service : DesiredService;
- END; (* RECORD *)
- VAR
- latestCar : ARRAY
- DesiredService OF CARDINAL;
- (* numbers of last cars created *)
-
- CarWashEntrance : SimulationQueue;
- timeLimit : Duration; (* extent of simulation *)
- numberOfWashers : CARDINAL;
- (* number of servers *)
-
-
- PROCEDURE LoggitWasher( washer : CARDINAL;
- s : ARRAY OF CHAR;
- type : DesiredService;
- car : CARDINAL );
- BEGIN
- WriteCard( CurrentTime(),6 );
- Write(" ");
- WriteString("Washer");
- WriteCard( washer,3 );
- Write(" ");
- IF type = Wash
- THEN
- WriteString("(Wash");
- ELSE
- WriteString("(WashAndWax");
- END; (* IF *)
- WriteCard( car,3 );
- WriteString(") ");
- WriteString( s );
- WriteLn;
- END LoggitWasher;
-
- PROCEDURE LoggitCar( car : CARDINAL;
- s : ARRAY OF CHAR;
- type : DesiredService );
- BEGIN
- WriteCard( CurrentTime(),6 );
- Write(" ");
- IF type = Wash
- THEN
- WriteString("Wash ");
- ELSE
- WriteString("WashAndWax ");
- END; (* IF *)
- WriteCard( car,3 );
- Write(" ");
- WriteString( s );
- WriteLn;
- END LoggitCar;
-
- PROCEDURE SimulateWasher( parameterAddress : ADDRESS );
- VAR
- wpp : POINTER TO WasherParams;
- whoAmI : CARDINAL; (* number of this washer *)
- r : Requester; (* who is being served *)
- sType : POINTER TO ServiceParams;
- service : DesiredService;
- car : CARDINAL;
- BEGIN
- wpp := parameterAddress;
- whoAmI := wpp^.WhoAmI;
- LOOP
- Serve( CarWashEntrance, sType, r);
- WITH sType^ DO
- service := Service;
- car := Car;
- END; (* WITH *)
-
- (* wash car *)
- LoggitWasher( whoAmI,"Washing car.",
- service,car );
- Hold( UniformDistribution(
- MinWashTime, MaxWashTime
- ) );
- LoggitWasher( whoAmI,"Wash complete.",
- service,car );
- IF service = WashAndWax
- THEN (* also wax car *)
- LoggitWasher( whoAmI,"Waxing car.",
- service,car );
- Hold( UniformDistribution(
- MinWaxTime, MaxWaxTime ) );
- LoggitWasher( whoAmI,"Wax complete.",
- service,car );
- END; (* IF *)
-
- Reactivate( r );
- LoggitWasher( whoAmI,"Ready for next car.",
- service,car );
- END; (* LOOP *)
- END SimulateWasher;
-
- PROCEDURE CreateNewCar( type : DesiredService ); FORWARD;
-
- PROCEDURE SimulateCar( parameterAddress : ADDRESS );
- VAR
- cpp : POINTER TO CarParams;
- whoAmI : CARDINAL; (* number of this car *)
- type : DesiredService;
- mean : Duration; (* mean inter-arrival time *)
- carDesc : ServiceParams;
- BEGIN
- cpp := parameterAddress;
- type := cpp^.type;
- whoAmI := cpp^.WhoAmI;
- IF whoAmI = 1
- THEN (* start running right away *)
- ELSE (* delay to simulate random arrival time *)
- CASE type OF
- Wash : mean := WashArrivalMean |
- WashAndWax : mean
- := WashAndWaxArrivalMean;
- END; (* CASE *)
- Hold( ExponentialDistribution( mean ) );
- END; (* IF *)
-
- CreateNewCar( type ); (* create next car of this
- type *)
-
- LoggitCar( whoAmI,"Entering car wash entrance.",
- type );
- WITH carDesc DO
- Service := type;
- Car := whoAmI;
- END; (* WITH *)
- (* queue up for service *)
- PlaceOrder( CarWashEntrance, ADR(carDesc) );
- LoggitCar( whoAmI,"Leaving car wash.",type );
-
- HaltThread; (* service over,
- car disappears into sunset *)
- END SimulateCar;
-
- PROCEDURE CreateNewCar( type : DesiredService );
- VAR
- cp : CarParams;
- BEGIN
- IF CurrentTime() < timeLimit
- THEN
- INC(latestCar[type]);
- cp.WhoAmI := latestCar[type];
- cp.type := type;
- CreateNewThread( SimulateCar,ADR(cp),WS);
- ELSE
- HaltSimulation;
- END; (* IF *)
- END CreateNewCar;
-
- PROCEDURE InitSimulation;
- VAR
- i : DesiredService; (* loop control *)
- n : CARDINAL; (* loop control *)
- wp : WasherParams;
- dur : CARDINAL;
-
- BEGIN
- WritePString("How many washers are there? ");
- ReadCard( numberOfWashers );
- WritePString(
- "How long should the simulation run (minutes) ? ");
- ReadCard( dur );
- timeLimit := dur * 100;
- (* Duration is in 0.01-minute units *)
- WriteString("****** Simulation run with ");
- WriteCard( numberOfWashers,3 );
- WriteString(" washers,");
- WriteLn;
- WriteString("****** for a duration of ");
- WriteCard( timeLimit,6 );
- WriteString(".");
- WriteLn;
-
- FOR i := MIN(DesiredService)
- TO MAX(DesiredService) DO
- latestCar[i] := 0;
- END; (* FOR *)
- InitializeQueue( CarWashEntrance );
-
- (* Create all washers *)
- FOR n := 1 TO numberOfWashers DO
- wp.WhoAmI := n;
- CreateNewThread( SimulateWasher,ADR(wp),WS );
- END; (* FOR *)
-
- (* Create one of each kind of car *);
- CreateNewCar( Wash );
- CreateNewCar( WashAndWax );
-
- END InitSimulation;
-
- BEGIN
- InitSimulation;
- HaltThread;
- END CarWash.